package com.kaizeli.website.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kaizeli.website.exception.BusinessErrorEnum;
import com.kaizeli.website.exception.BusinessException;
import com.kaizeli.website.mapper.EmployeeMapper;
import com.kaizeli.website.pojo.dto.base.PageDTO;
import com.kaizeli.website.pojo.model.EmployeeDO;
import com.kaizeli.website.pojo.vo.EmployeeVO;
import com.kaizeli.website.query.EmployeeQuery;
import com.kaizeli.website.service.EmployeeService;
import com.kaizeli.website.util.AsserterUtil;
import com.kaizeli.website.util.DateTimeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 员工服务实现类
 */
@Service
@RequiredArgsConstructor
public class EmployeeServiceImpl implements EmployeeService {
    
    private final EmployeeMapper employeeMapper;
    
    @Override
    public PageDTO<EmployeeVO> pageQuery(EmployeeQuery query) {
        // 构建查询条件
        LambdaQueryWrapper<EmployeeDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(query.getEmployeeCode()), EmployeeDO::getEmployeeCode, query.getEmployeeCode())
                .like(StrUtil.isNotBlank(query.getName()), EmployeeDO::getName, query.getName())
                .eq(StrUtil.isNotBlank(query.getGender()), EmployeeDO::getGender, query.getGender())
                .like(StrUtil.isNotBlank(query.getPhone()), EmployeeDO::getPhone, query.getPhone())
                .like(StrUtil.isNotBlank(query.getEmail()), EmployeeDO::getEmail, query.getEmail())
                .like(StrUtil.isNotBlank(query.getDepartment()), EmployeeDO::getDepartment, query.getDepartment())
                .like(StrUtil.isNotBlank(query.getPosition()), EmployeeDO::getPosition, query.getPosition())
                .eq(query.getStatus() != null, EmployeeDO::getStatus, query.getStatus())
                .eq(StrUtil.isNotBlank(query.getEmployeeType()), EmployeeDO::getEmployeeType, query.getEmployeeType())
                .eq(StrUtil.isNotBlank(query.getMaritalStatus()), EmployeeDO::getMaritalStatus, query.getMaritalStatus())
                .like(StrUtil.isNotBlank(query.getNativePlace()), EmployeeDO::getNativePlace, query.getNativePlace())
                .eq(StrUtil.isNotBlank(query.getPoliticalStatus()), EmployeeDO::getPoliticalStatus, query.getPoliticalStatus())
                .eq(StrUtil.isNotBlank(query.getEducation()), EmployeeDO::getEducation, query.getEducation())
                .like(StrUtil.isNotBlank(query.getMajor()), EmployeeDO::getMajor, query.getMajor())
                .orderByDesc(EmployeeDO::getCreateTime);
        
        // 分页查询
        Page<EmployeeDO> page = employeeMapper.selectPage(query.toMpPage(), wrapper);
        
        // 转换为VO
        return PageDTO.of(page, this::convertToVO);
    }
    
    @Override
    public EmployeeVO getById(Long id) {
        AsserterUtil.notNull(id, BusinessErrorEnum.EMPLOYEE_ID_NOT_NULL);
        
        EmployeeDO employeeDO = employeeMapper.selectById(id);
        if (employeeDO == null) {
            throw new BusinessException(BusinessErrorEnum.EMPLOYEE_NOT_FOUND);
        }
        
        return convertToVO(employeeDO);
    }
    
    @Override
    public EmployeeVO getByEmployeeCode(String employeeCode) {
        AsserterUtil.notNull(employeeCode, BusinessErrorEnum.EMPLOYEE_CODE_NOT_NULL);
        
        EmployeeDO employeeDO = employeeMapper.selectByEmployeeCode(employeeCode);
        if (employeeDO == null) {
            throw new BusinessException(BusinessErrorEnum.EMPLOYEE_NOT_FOUND);
        }
        
        return convertToVO(employeeDO);
    }
    
    @Override
    public Long save(EmployeeDO employeeDO) {
        AsserterUtil.notNull(employeeDO, BusinessErrorEnum.EMPLOYEE_INFO_NOT_NULL);
        
        // 验证必填字段
        AsserterUtil.notNull(employeeDO.getEmployeeType(), BusinessErrorEnum.EMPLOYEE_TYPE_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getName(), BusinessErrorEnum.EMPLOYEE_NAME_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getGender(), BusinessErrorEnum.EMPLOYEE_GENDER_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getMaritalStatus(), BusinessErrorEnum.EMPLOYEE_MARITAL_STATUS_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getNativePlace(), BusinessErrorEnum.EMPLOYEE_NATIVE_PLACE_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getPoliticalStatus(), BusinessErrorEnum.EMPLOYEE_POLITICAL_STATUS_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getBirthday(), BusinessErrorEnum.EMPLOYEE_BIRTHDAY_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getIdCard(), BusinessErrorEnum.EMPLOYEE_ID_CARD_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getRegisteredAddress(), BusinessErrorEnum.EMPLOYEE_REGISTERED_ADDRESS_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getPhone(), BusinessErrorEnum.EMPLOYEE_PHONE_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getWechat(), BusinessErrorEnum.EMPLOYEE_WECHAT_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getEmail(), BusinessErrorEnum.EMPLOYEE_EMAIL_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getEducation(), BusinessErrorEnum.EMPLOYEE_EDUCATION_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getMajor(), BusinessErrorEnum.EMPLOYEE_MAJOR_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getGraduationDate(), BusinessErrorEnum.EMPLOYEE_GRADUATION_DATE_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getEmergencyContact(), BusinessErrorEnum.EMPLOYEE_EMERGENCY_CONTACT_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getEmergencyPhone(), BusinessErrorEnum.EMPLOYEE_EMERGENCY_PHONE_NOT_NULL);
        
        // 检查员工编号是否已存在（如果提供了员工编号）
        if (StrUtil.isNotBlank(employeeDO.getEmployeeCode())) {
            EmployeeDO existEmployee = employeeMapper.selectByEmployeeCode(employeeDO.getEmployeeCode());
            if (existEmployee != null) {
                throw new BusinessException(BusinessErrorEnum.EMPLOYEE_CODE_DUPLICATE);
            }
        }
        
        // 设置默认状态为在职
        if (employeeDO.getStatus() == null) {
            employeeDO.setStatus(1);
        }
        
        // 设置默认值
        if (employeeDO.getContractRenewed() == null) {
            employeeDO.setContractRenewed("否");
        }
        if (employeeDO.getRenewalCount() == null) {
            employeeDO.setRenewalCount(0);
        }
        if (employeeDO.getEntryForm() == null) {
            employeeDO.setEntryForm("未上传");
        }
        if (employeeDO.getIdCardCopy() == null) {
            employeeDO.setIdCardCopy("未上传");
        }
        if (employeeDO.getDiploma() == null) {
            employeeDO.setDiploma("未上传");
        }
        if (employeeDO.getDegreeCertificate() == null) {
            employeeDO.setDegreeCertificate("未上传");
        }
        if (employeeDO.getBankCardCopy() == null) {
            employeeDO.setBankCardCopy("未上传");
        }
        if (employeeDO.getResume() == null) {
            employeeDO.setResume("未上传");
        }
        if (employeeDO.getLeavingCertificate() == null) {
            employeeDO.setLeavingCertificate("未上传");
        }
        if (employeeDO.getMedicalReport() == null) {
            employeeDO.setMedicalReport("未上传");
        }
        if (employeeDO.getConfidentialityAgreement() == null) {
            employeeDO.setConfidentialityAgreement("未上传");
        }
        if (employeeDO.getTrainingAgreement() == null) {
            employeeDO.setTrainingAgreement("未上传");
        }
        if (employeeDO.getRulesConfirmation() == null) {
            employeeDO.setRulesConfirmation("未上传");
        }
        if (employeeDO.getCodeOfConduct() == null) {
            employeeDO.setCodeOfConduct("未上传");
        }
        
        employeeMapper.insert(employeeDO);
        return employeeDO.getId();
    }
    
    @Override
    public Boolean update(EmployeeDO employeeDO) {
        AsserterUtil.notNull(employeeDO, BusinessErrorEnum.EMPLOYEE_INFO_NOT_NULL);
        AsserterUtil.notNull(employeeDO.getId(), BusinessErrorEnum.EMPLOYEE_ID_NOT_NULL);
        
        // 检查员工是否存在
        EmployeeDO existEmployee = employeeMapper.selectById(employeeDO.getId());
        if (existEmployee == null) {
            throw new BusinessException(BusinessErrorEnum.EMPLOYEE_NOT_FOUND);
        }
        
        // 如果更新员工编号，检查是否重复
        if (StrUtil.isNotBlank(employeeDO.getEmployeeCode()) && 
            !employeeDO.getEmployeeCode().equals(existEmployee.getEmployeeCode())) {
            EmployeeDO duplicateEmployee = employeeMapper.selectByEmployeeCode(employeeDO.getEmployeeCode());
            if (duplicateEmployee != null) {
                throw new BusinessException(BusinessErrorEnum.EMPLOYEE_CODE_DUPLICATE);
            }
        }
        
        int result = employeeMapper.updateById(employeeDO);
        return result > 0;
    }
    
    @Override
    public Boolean deleteById(Long id) {
        AsserterUtil.notNull(id, BusinessErrorEnum.EMPLOYEE_ID_NOT_NULL);
        
        // 检查员工是否存在
        EmployeeDO existEmployee = employeeMapper.selectById(id);
        if (existEmployee == null) {
            throw new BusinessException(BusinessErrorEnum.EMPLOYEE_NOT_FOUND);
        }
        
        int result = employeeMapper.deleteById(id);
        return result > 0;
    }
    
    @Override
    public Boolean deleteBatchByIds(List<Long> ids) {
        AsserterUtil.notNull(ids, BusinessErrorEnum.EMPLOYEE_ID_NOT_NULL);
        AsserterUtil.isTrue(!ids.isEmpty(), BusinessErrorEnum.EMPLOYEE_ID_NOT_NULL);
        
        int result = employeeMapper.deleteBatchIds(ids);
        return result > 0;
    }
    
    @Override
    public Boolean updateStatus(Long id, Integer status) {
        AsserterUtil.notNull(id, BusinessErrorEnum.EMPLOYEE_ID_NOT_NULL);
        AsserterUtil.notNull(status, BusinessErrorEnum.EMPLOYEE_STATUS_INVALID);
        AsserterUtil.isTrue(status == 0 || status == 1, BusinessErrorEnum.EMPLOYEE_STATUS_INVALID);
        
        // 检查员工是否存在
        EmployeeDO existEmployee = employeeMapper.selectById(id);
        if (existEmployee == null) {
            throw new BusinessException(BusinessErrorEnum.EMPLOYEE_NOT_FOUND);
        }
        
        EmployeeDO updateEmployee = new EmployeeDO();
        updateEmployee.setId(id);
        updateEmployee.setStatus(status);
        
        int result = employeeMapper.updateById(updateEmployee);
        return result > 0;
    }
    
    @Override
    public List<EmployeeVO> getEmployeesByStatus(Integer status) {
        AsserterUtil.notNull(status, BusinessErrorEnum.EMPLOYEE_STATUS_INVALID);
        AsserterUtil.isTrue(status == 0 || status == 1, BusinessErrorEnum.EMPLOYEE_STATUS_INVALID);
        
        // 构建查询条件
        LambdaQueryWrapper<EmployeeDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EmployeeDO::getStatus, status)
                .orderByDesc(EmployeeDO::getCreateTime);
        
        // 查询员工列表
        List<EmployeeDO> employeeList = employeeMapper.selectList(wrapper);
        
        // 转换为VO
        return employeeList.stream()
                .map(this::convertToVO)
                .collect(java.util.stream.Collectors.toList());
    }
    
    /**
     * 将EmployeeDO转换为EmployeeVO
     */
    private EmployeeVO convertToVO(EmployeeDO employeeDO) {
        EmployeeVO vo = BeanUtil.copyProperties(employeeDO, EmployeeVO.class);
        
        // 转换状态描述
        if (employeeDO.getStatus() != null) {
            vo.setStatusDesc(employeeDO.getStatus() == 1 ? "在职" : "离职");
        }
        
        // 转换时间格式
        if (employeeDO.getCreateTime() != null) {
            vo.setCreateTime(DateTimeUtil.converToDateTime(employeeDO.getCreateTime().toString()));
        }
        if (employeeDO.getUpdateTime() != null) {
            vo.setUpdateTime(DateTimeUtil.converToDateTime(employeeDO.getUpdateTime().toString()));
        }
        
        return vo;
    }
    
    @Override
    public List<EmployeeVO> search(String keyword) {
        QueryWrapper<EmployeeDO> wrapper = new QueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(keyword), "name", keyword)
                .or()
                .like(StrUtil.isNotBlank(keyword), "employee_code", keyword)
                .orderByDesc("create_time");
        
        List<EmployeeDO> list = employeeMapper.selectList(wrapper);
        return list.stream().map(this::convertToVO).collect(java.util.stream.Collectors.toList());
    }
    
    @Override
    public List<EmployeeVO> getAllEmployees() {
        List<EmployeeDO> list = employeeMapper.selectList(null);
        return list.stream().map(this::convertToVO).collect(java.util.stream.Collectors.toList());
    }
}